home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
recio202.zip
/
recio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-05
|
14KB
|
406 lines
/*****************************************************************************
MODULE: recio.c
PURPOSE: record input/output functions
COPYRIGHT: (C) 1994 William Pierpoint
COMPILER: Borland C Version 3.1
OS: MSDOS Version 6.2
VERSION: 2.02
RELEASE: May 5, 1994
*****************************************************************************/
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "recio.h"
#define rcol(rp) ((rp)->r_colno)
#define rflags(rp) ((rp)->r_flags)
#define rfd(rp) ((rp)->r_fd)
#define rfp(rp) ((rp)->r_fp)
#define rreclen(rp) ((rp)->r_reclen)
#define rrecsiz(rp) ((rp)->r_recsiz)
#define rfldsiz(rp) ((rp)->r_fldsiz)
#define rfldch(rp) ((rp)->r_fldch)
#define rtxtch(rp) ((rp)->r_txtch)
/* private module variables */
static REC *_RECS = NULL; /* ptr to array of REC structures */
static REC rin = { 1, 0, stdin, "stdin", 0L,
0, 0, 0, 0, NULL,
0, NULL, RECFLDCH, RECTXTCH, RECIN };
static REC rout = { 2, _R_WRT, stdout, "stdout", 0L,
0, 0, 0, 0, NULL,
0, NULL, RECFLDCH, RECTXTCH, RECOUT };
static REC rerr = { 3, _R_WRT, stderr, "stderr", 0L,
0, 0, 0, 0, NULL,
0, NULL, RECFLDCH, RECTXTCH, RECERR };
#if defined (__MSDOS__) || (MSDOS)
static REC rprn = { 4, _R_WRT, stdprn, "stdprn", 0L,
0, 0, 0, 0, NULL,
0, NULL, RECFLDCH, RECTXTCH, RECPRN };
#define NREC 4 /* number of static record streams */
#else
#define NREC 3
#endif
#define ROPEN_MIN NREC /* reserved for recin, etc */
#define ROPEN max(ROPEN_MAX, ROPEN_MIN)
/* public variables */
REC *recin = &rin;
REC *recout = &rout;
REC *recerr = &rerr;
#if defined (__MSDOS__) || (MSDOS)
REC *recprn = &rprn;
#endif
/* friend variables */
char _r_nsbuf[NSBUFSIZ]; /* buffer for numeric to string conversions */
/* Support functions */
/****************************************************************************/
static void /* returns nothing */
_rexit( /* at program exit, clean up */
void) /* no arguments */
/****************************************************************************/
{
/* free recin buffers */
free(rflds(recin));
free(rrecs(recin));
rflds(recin) = NULL;
rfldsiz(recin) = 0;
rrecs(recin) = NULL;
rrecsiz(recin) = 0;
rreclen(recin) = 0;
/* ensure all record streams closed */
rcloseall();
}
/****************************************************************************/
void /* return error number (0=no error) */
_rsetexitfn( /* register _rexit function with atexit() */
REC *rp) /* record pointer */
/****************************************************************************/
{
static int once=0; /* register exit fn only once */
if (!once) {
/* execute this path at most one time */
once++;
/* if atexit() fails to register _rexit() function */
if (atexit(_rexit)) {
/* register warning */
rsetwarn(rp, R_WNOREG);
}
}
}
/****************************************************************************/
int /* return error number (0=no error) */
_rismode( /* check for correct mode */
REC *rp, /* record pointer */
int mode) /* mode (0=read; !0=write/append) */
/****************************************************************************/
{
int errnum=0; /* error number (0=mode ok, !0=invalid mode) */
unsigned smode; /* stream mode */
/* if stream _R_WRT flag does not match mode */
smode = rflags(rp) & _R_WRT;
if ((mode && !smode) || (!mode && smode)) {
errnum = rseterr(rp, R_EINVMOD);
}
return errnum;
}
/****************************************************************************/
int /* return error number (0=no error) */
_rstatus( /* check stream for errors */
REC *rp, /* record pointer */
int mode) /* mode (0=read; !0=write/append) */
/****************************************************************************/
{
int errnum=0; /* error number */
/* test for valid record pointer */
if (!risvalid(rp)) {
errnum = rseterr(NULL, EINVAL);
goto done;
}
/* check mode */
errnum = _rismode(rp, mode);
if (errnum) goto done;
/* if record 0 and write mode */
if (!rrecno(rp) && mode) {
rrecno(rp)++;
}
/* test for previous error */
errnum = rerror(rp);
done:
return (errnum);
}
/****************************************************************************/
static void /* returns nothing */
_rfree( /* free the memory allocated to a record */
REC *rp) /* record pointer */
/****************************************************************************/
{
if (risvalid(rp)) {
free(rflds(rp));
free(rrecs(rp));
if (rfp(rp)) fclose(rfp(rp));
memset(rp, 0, sizeof(REC));
}
}
/* User functions */
/****************************************************************************/
REC * /* return record pointer */
ropen( /* open a record stream for reading */
const char *fname, /* name of file to open */
const char *mode) /* type of mode used to open file */
/****************************************************************************/
{
REC *rp = _RECS; /* record pointer */
int i; /* count of REC structures */
int ch; /* first character of mode */
errno = 0;
/* only modes currently supported are "r", "w", and "a" */
ch = tolower(*mode);
if (!(ch=='r' || ch=='w' || ch=='a')) {
rp = NULL;
rseterr(NULL, EINVAL);
goto done;
}
/* allocate memory for array of REC structures */
if (!rp) {
do {
/* note: no memory allocation needed for recin, etc */
rp = _RECS = (REC *) calloc(ROPEN-NREC, sizeof(REC));
if (!rp) {
if (rseterr(NULL, ENOMEM)) goto done;
}
} while (!rp);
}
/* search thru REC structures until empty position found */
for (i=NREC+1; i <= ROPEN; i++, rp++) {
if (!rfd(rp)) {
rfd(rp) = i;
break;
}
}
/* error if out of positions */
if (i > ROPEN) {
rp = NULL;
rseterr(NULL, EMFILE);
goto done;
}
/* open file */
rfp(rp) = fopen(fname, mode);
if (!rfp(rp)) {
rclose(rp);
rp = NULL;
/* if error other than path/file not found */
if (errno != ENOENT) {
rseterr(NULL, errno);
}
goto done;
}
/* initialize */
if (ch != 'r') rflags(rp) |= _R_WRT;
rnames(rp) = fname;
rrecno(rp) = 0L;
rfldno(rp) = 0;
rcol(rp) = 0;
rrecsiz(rp) = 0;
rreclen(rp) = 0;
rrecs(rp) = NULL;
rfldsiz(